package cn.b.sky.mes.hr.controller;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.b.sky.mes.hr.model.Performance;
import cn.b.sky.mes.hr.model.Shifting;
import cn.b.sky.mes.hr.model.ShiftingPermission;
import cn.b.sky.mes.hr.model.condition.PerformanceCondition;
import cn.b.sky.mes.hr.service.PerformanceService;
import cn.b.sky.mes.hr.service.ShiftingPermissionService;
import cn.b.sky.mes.hr.service.ShiftingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.b.sky.common.constants.SystemConstant;
import cn.b.sky.common.enums.DwzCallbackType;
import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.model.DWZResult;
import cn.b.sky.common.utils.DateUtils;
import cn.b.sky.user.SecurityContextUtil;
import cn.b.sky.user.controller.SecurityController;

/**
 * 
 * <strong>Title : PerformanceController.java<br></strong>
 * <strong>Package : cn.b.sky.mes.hr.controller<br></strong>
 * <strong>Description : </strong>绩效台账控制器<br> 
 * <strong>Create on : 2016-5-13 下午2:46:05<br></strong>
 * <p>
 * @author lidapeng<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人|修改日期|修改描述<br>
 * -------------------------------------------<br>
 * <br>
 * <br>
 */
@Controller
@RequestMapping("/performance/*")
@Slf4j
public class PerformanceController extends SecurityController {
  @Resource
  private PerformanceService performanceService;

  @Resource
  private ShiftingService shiftingService;

  @Resource
  private ShiftingPermissionService shiftingPermissionService;

  @RequestMapping("performanceList")
  public String performanceList(@ModelAttribute("condition") PerformanceCondition condition, String navTabId,
                                Model model) {
    condition.setSiteCode(this.getSiteCode());
    //获取当前用户的工作中心权限
    List<ShiftingPermission> workCenters = shiftingPermissionService.getPermissionsByUser(this.getSiteCode(),
        SecurityContextUtil.getCurrentUserName(), null);
    //没有工作中心权限则不过滤
    if (workCenters == null || workCenters.size() <= 0) {
      condition.setData(new ArrayList<Performance>());
      condition.setTotalCount(0);
    } else {
      condition.setPermission(workCenters);
      List<Performance> performances = performanceService.getPerformancesByCondition(condition);
      int count = performanceService.getPerformancesCountByCondition(condition);
      condition.setData(performances);
      condition.setTotalCount(count);
    }
    model.addAttribute("page", condition);

    model.addAttribute(NAVTABID, navTabId);
    return "hr/performance/performance_list";
  }

  @RequestMapping("addPerformance")
  public String addPerformance(String navTabId, Model model) {
    model.addAttribute(NAVTABID, navTabId);
    return "hr/performance/performance_add";
  }

  @RequestMapping("batchAddPerformance")
  public String batchAddPerformance(String navTabId, Model model) {
    model.addAttribute(NAVTABID, navTabId);

    return "hr/performance/batch_performance_add";
  }

  /**
   * 
   * <strong>Title : getShiftListPerformance<br></strong>
   * <strong>Description : </strong>获取人员某天的排班情况<br> 
   * <strong>Create on : 2016-3-31 上午11:14:29<br></strong>
   * <p>
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("getShiftListPerformance")
  public String getShiftListPerformance(String personnelCode, String theDate, String navTabId, Model model) {
    if (StringUtils.isBlank(personnelCode) || StringUtils.isBlank(theDate)) {
      throw ImeException.newException(SystemConstant.PARAMETERNULL);
    }
    List<Shifting> shifts = shiftingService.getNotPerformancesShiftingByPersonnelAndDate(this.getSiteCode(),
        personnelCode, theDate);
    if (shifts == null || shifts.size() <= 0) {
      throw ImeException.newException("noShiftingNotPerformance.M");
    }
    model.addAttribute(NAVTABID, navTabId);
    model.addAttribute("personnelCode", personnelCode);
    model.addAttribute("theDate", theDate);
    model.addAttribute("shifting", shifts);
    return "hr/performance/shift_list";
  }

  /**
   * 
   * <strong>Title : getBatchShiftListPerformance<br></strong>
   * <strong>Description : </strong>批量启用排班录入绩效获取工作中心下面的绩效<br> 
   * <strong>Create on : 2016-4-5 上午9:46:39<br></strong>
   * <p>
   * @param personnelCode 
   * @param theDate
   * @param navTabId
   * @param model
   * @return
   * String
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  @RequestMapping("getBatchShiftListPerformance")
  public String getBatchShiftListPerformance(@ModelAttribute("performance") Performance performance, String navTabId,
      Model model) {
    if (performance == null || StringUtils.isBlank(performance.getWorkCenterCode()) || performance.getTheDate() == null
        || performance.getQuantity() == null) {
      throw ImeException.newException(SystemConstant.PARAMETERNULL);
    }
    List<Shifting> shifts = shiftingService.getNotPerformancesShiftingByWorkcenterAndDate(this.getSiteCode(),
        performance.getWorkCenterCode(), DateUtils.getDateUtils(DateUtils.YYYY_MM_DD).format(performance.getTheDate()));
    if (shifts == null || shifts.size() <= 0) {
      throw ImeException.newException("workCenterNoShiftingNotPerformance.M");
    }
    model.addAttribute(NAVTABID, navTabId);
    model.addAttribute("shifting", shifts);
    return "hr/performance/batchShift_list";
  }

  @RequestMapping("modifyPerformance")
  public String modifyPerformance(Long id, String navTabId, Model model) {

    if (id == null) {
      throw ImeException.newException(SystemConstant.PARAMETERNULL);
    }
    Performance performance = performanceService.getPerformanceById(id, this.getSiteCode());
    model.addAttribute("performance", performance);
    model.addAttribute(NAVTABID, navTabId);
    //业务需求改变去掉排班变量，绩效和排班无关
    /* ParameterEntity parameter = parameterService.getParameterEntityByCode(ParameterEnums.ENABLESHIFT.getCode(),
         this.getSiteCode());
     if (HrConstans.SHIFTING_ENABLE_YES.equals(parameter.getDefaultValue())) {
       return "hr/performance/performanceshift_edit";
     } else {
       return "hr/performance/performance_edit";
     }*/
    return "hr/performance/performance_edit";
  }

  @RequestMapping("viewPerformance")
  public String viewPerformance(Long id, String navTabId, Model model) {
    if (id == null) {
      throw ImeException.newException(SystemConstant.PARAMETERNULL);
    }

    Performance performance = performanceService.getPerformanceById(id, this.getSiteCode());
    model.addAttribute("performance", performance);
    model.addAttribute(NAVTABID, navTabId);
    return "hr/performance/performance_view";
  }

  @RequestMapping("savePerformance")
  @ResponseBody
  public DWZResult savePerformance(Performance performance, Model model, String navTabId) {
    if (performance == null || StringUtils.isBlank(performance.getPersonnelCode())) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }
    /* ParameterEntity parameter = parameterService.getParameterEntityByCode(ParameterEnums.ENABLESHIFT.getCode(),
         this.getSiteCode());
     if (HrConstans.SHIFTING_ENABLE_YES.equals(parameter.getDefaultValue())) {
       if (performance.getPerformances().size() <= 0) {
         return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
       }
       for (Performance p : performance.getPerformances()) {
         p.setPersonnelCode(performance.getPersonnelCode());
         p.setTheDate(performance.getTheDate());
         p.setSiteCode(this.getSiteCode());
         this.setCreateInfo(p);
         if (!this.checkPerformanceDate(p)) {
           return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "exceptionPeriodOver.M"));
         }
         if (performanceService.isExsitsPerformance(p)) {
           return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "personnelExistsPerformance.M"));
         }
         performanceService.savePerformance(p);
       }
     } else {*/
    //没有排班的就直接保存
    if (performance.isNullObject()) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }
    performance.setSiteCode(this.getSiteCode());
    this.setCreateInfo(performance);
    if (!this.checkPerformanceDate(performance)) {
      return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "exceptionPeriodOver.M"));
    }
    if (performanceService.isExsitsPerformance(performance)) {
      return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "personnelExistsPerformance.M"));
    }
    performanceService.savePerformance(performance);
    //}
    return dialogAjaxDone(navTabId, null, null, performance);
  }

  @RequestMapping("saveBatchPerformance")
  @ResponseBody
  public DWZResult saveBatchPerformance(Performance performance, Model model, String navTabId,
      HttpServletRequest request) throws ParseException {
    if (performance.getPerformances().size() <= 0) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }
    String message = "";
    List<BatchJobReport> reports = new ArrayList<BatchJobReport>();
    int failures = 0;
    /* 去掉排班判断，业务更改
     * ParameterEntity parameter = parameterService.getParameterEntityByCode(ParameterEnums.ENABLESHIFT.getCode(),
         this.getSiteCode());
     if (HrConstans.SHIFTING_ENABLE_YES.equals(parameter.getDefaultValue())) {
       if (performance == null || StringUtils.isBlank(performance.getWorkCenterCode())
           || performance.getTheDate() == null) {
         return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
       }
       for (Performance p : performance.getPerformances()) {
         if (p == null) {
           continue;
         }
         p.setWorkCenterCode(performance.getWorkCenterCode());
         p.setTheDate(performance.getTheDate());
         p.setSiteCode(this.getSiteCode());
         this.setCreateInfo(p);
         if (!this.checkPerformanceDate(p)) {
           message += getImeViewMessageI18n(getCurrentLanguage(), "batchPerformanceError24.M", p.getPersonnelCode(),
               DateUtils.getDateUtils().format(p.getStartDatetime()), DateUtils.getDateUtils()
                   .format(p.getEndDatetime()));
           reports.add(new BatchJobReport(p.getPersonnelCode(), message, false, this.getCurrentLanguage(), this.getSiteCode()));
           failures++;
           continue;
         }
         if (!performanceService.isExsitsPerformance(p)) {//批量保存已存在就不保存，其余的继续保存
           performanceService.savePerformance(p);
         } else {
           message += getImeViewMessageI18n(getCurrentLanguage(), "batchPerformanceError.M", p.getPersonnelCode(),
               DateUtils.getDateUtils().format(p.getStartDatetime()), DateUtils.getDateUtils()
                   .format(p.getEndDatetime()));
           reports.add(new BatchJobReport(performance.getPersonnelCode(), message, false, this.getCurrentLanguage(), this.getSiteCode()));
           failures++;
         }
       }
     } else {*/
    if (!this.checkPerformanceDate(performance)) {
      return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "exceptionPeriodOver.M"));
    }
    //没有排班的就直接保存
    for (Performance p : performance.getPerformances()) {
      if (p == null || StringUtils.isBlank(p.getPersonnelCode())) {
        continue;
      }
      performance.setId(null);//初始化置空
      performance.setPersonnelCode(p.getPersonnelCode());
      performance.setPersonnelTypeCode(p.getPersonnelTypeCode());
      performance.setWorkCenterCode(p.getWorkCenterCode());
      performance.setSiteCode(this.getSiteCode());
      if (!this.checkPerformanceDate(performance)) {
        message += getImeViewMessageI18n(getCurrentLanguage(), "batchPerformanceError24.M",
            performance.getPersonnelCode(), DateUtils.getDateUtils().format(performance.getStartDatetime()), DateUtils
                .getDateUtils().format(performance.getEndDatetime()));
        reports.add(new BatchJobReport(performance.getPersonnelCode(), message, false, this.getCurrentLanguage(), this
            .getSiteCode()));
        failures++;
        continue;
      }
      if (performance.isNullObject()) {
        return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
      }
      this.setCreateInfo(performance);
      if (!performanceService.isExsitsPerformance(performance)) {
        performanceService.savePerformance(performance);
      } else {
        message += getImeViewMessageI18n(getCurrentLanguage(), "batchPerformanceError.M",
            performance.getPersonnelCode(), DateUtils.getDateUtils().format(performance.getStartDatetime()), DateUtils
                .getDateUtils().format(performance.getEndDatetime()));
        reports.add(new BatchJobReport(performance.getPersonnelCode(), message, false, this.getCurrentLanguage(), this
            .getSiteCode()));
        failures++;
      }
    }
    //}

    if (failures == 0) {
      return dialogAjaxDone(navTabId, null, null, null);
    } else {
      return batchjobAjaxDone(request, DwzCallbackType.CLOSECURRENT, reports);
    }
  }

  /**
   * 
   * <strong>Title : checkPerformanceDate<br></strong>
   * <strong>Description : </strong>判断人员的时间范围,开始时间不能小于当天并且日期范围不能大于24小时<br> 
   * <strong>Create on : 2016-3-29 下午5:40:11<br></strong>
   * <p>
   * @param performance
   * @return
   * @throws ParseException
   * boolean
   * @throws 
   * @author lidapeng<br>
   * @version <strong>v1.0.0</strong><br>
   * <br>
   * <strong>修改历史:</strong><br>
   * 修改人 | 修改日期 | 修改描述<br>
   * -------------------------------------------<br>
   * <br>
   * <br>
   */
  private boolean checkPerformanceDate(Performance performance) {

    DateUtils dateUtils = DateUtils.getDateUtils(DateUtils.YYYY_MM_DD_HH);
    Date theDate = performance.getTheDate();
    Date startDateTime = performance.getStartDatetime();
    Date endDateTime = performance.getEndDatetime();

    //开始时间大于结束时间，开始时间小于当前日期，结束时间比开始时间大24小时都不行
    if (startDateTime.after(endDateTime) || startDateTime.before(theDate)
        || dateUtils.getHoursOperationDate(startDateTime, endDateTime) > 24) {
      return false;
    }
    //人员比较
    if (!StringUtils.isBlank(performance.getPersonnelCode())) {
      List<Performance> performances = performanceService.getPerformanceBypersonnelAndTheDate(performance);
      if (performances != null && performances.size() > 0) {
        //开始时间比较
        Date minstart = performances.get(0).getStartDatetime();
        //最小的开始时间，和当前输入的结束时间不能超过24小时
        if (minstart.before(startDateTime) && dateUtils.getHoursOperationDate(minstart, endDateTime) > 24) {
          return false;
        }
        //结束时间比较,按照结束时间降序
        Collections.sort(performances, new Comparator<Performance>() {
          @Override
          public int compare(Performance p1, Performance p2) {
            if (p1.getEndDatetime().after(p2.getEndDatetime())) {
              return -1;
            } else {
              return 1;
            }
          }
        });
        //开始时间 和最大的结束时间 不能超过24小时
        Date maxend = performances.get(0).getEndDatetime();
        if (maxend.after(endDateTime) && dateUtils.getHoursOperationDate(startDateTime, maxend) > 24) {
          return false;
        }
      }
    }
    return true;
  }

  @RequestMapping("updatePerformance")
  @ResponseBody
  public DWZResult updatePerformance(Performance performance, Model model, String navTabId) throws ParseException {
    if (performance == null || performance.getId() == null) {
      return ajaxError(getImeViewMessageI18n(SecurityContextUtil.getLanguageCode(), SystemConstant.PARAMETERNULL));
    }

    performance.setSiteCode(this.getSiteCode());
    this.setCreateInfo(performance);
    if (!this.checkPerformanceDate(performance)) {
      return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "exceptionPeriodOver.M"));
    }
    if (performanceService.isExsitsPerformance(performance)) {
      return ajaxError(this.getImeViewMessageI18n(getCurrentLanguage(), "personnelExistsPerformance.M"));
    }
    performanceService.modifyPerformance(performance);

    return dialogAjaxDone(navTabId, null, null, null);
  }

  @RequestMapping("deletePerformance")
  @ResponseBody
  public DWZResult deletePerformance(String ids, String navTabId, Model model, HttpServletRequest request) {
    if (StringUtils.isBlank(ids)) {
      return ajaxError(getImeViewMessageI18n(null, SystemConstant.PARAMETERNULL));
    }
    String[] idArr = ids.split(",");
    List<BatchJobReport> reports = new ArrayList<BatchJobReport>();
    int failures = 0;
    for (int i = 0; i < idArr.length; i++) {
      String message = null;
      //如果主键没有下划线，则报错，删除失败，主键由personnelCode_personnelTypeCode组成
      try {
        message = performanceService.deletePerformanceById(Long.valueOf(idArr[i]));
        message = this.getImeViewMessageI18n(this.getCurrentLanguage(), message);
      } catch (Exception e) {
        log.error("{}", e);
        message = e.getMessage();
      }
      boolean flag = true;
      if (!StringUtils.isBlank(message)) {
        failures += 1;
        flag = false;
      }
      BatchJobReport report = new BatchJobReport(idArr[i], message, flag, this.getCurrentLanguage(), this.getSiteCode());
      reports.add(report);
    }
    if (failures == 0) {
      return navTabAjaxDone(navTabId, null, null, null,
          getImeViewMessageI18n(this.getCurrentLanguage(), "successfulOperation.M"), null);
    } else {
      return batchjobAjaxDone(request, reports);
    }
  }
}
